import streamlit as st
import pandas as pd
import pickle
from apriori import load_apriori, getAsso
from zhipuai import ZhipuAI
import json
from collections import defaultdict

# 初始化设置
st.set_page_config(page_title="技能-岗位精准推荐系统", layout="wide")
API_KEY = "9f268715eb52419cb903974883c23c01.L44iHUWY0e85QEMQ"

# 1. 数据加载
@st.cache_data
def load_data():
    dataset = pd.read_csv("招聘数据集(含技能列表）.csv")
    return dataset

dataset = load_data()
client = ZhipuAI(api_key=API_KEY)

# 2. 核心功能函数
def cacu_skill_position_wordcount(dataset, skill):
    """查找技能对应的前5个高频岗位"""
    skill = skill.lower()
    position_counter = defaultdict(int)
    
    for _, row in dataset.iterrows():
        if pd.notna(row['skill_list']):
            skills = [s.lower().strip() for s in row['skill_list'].split(',')]
            if skill in skills:
                position = row['positionName']
                position_counter[position] += 1
                
    return dict(sorted(position_counter.items(), key=lambda x: x[1], reverse=True)[:5])

def cacu_postion_skill_wordcount(dataset, position_name):
    """查找岗位需要的前5个核心技能"""
    skill_counter = defaultdict(int)
    
    for _, row in dataset.iterrows():
        if compare_str(row['positionName'], position_name):
            if pd.notna(row['skill_list']):
                for skill in row['skill_list'].split(','):
                    skill = skill.lower().strip()
                    if skill:
                        skill_counter[skill] += 1
                        
    return dict(sorted(skill_counter.items(), key=lambda x: x[1], reverse=True)[:5])

def get_associated_skills(target_skill):
    """获取关联技能并统计真实频次"""
    # 1. 获取关联技能集合
    skill_set = getAsso(load_apriori("apriori.bin"), target_skill.lower(), 0.1)
    
    # 2. 从原始数据统计这些技能的真实出现频次
    skill_counter = defaultdict(int)
    for _, row in dataset.iterrows():
        if pd.notna(row['skill_list']):
            skills = [s.lower().strip() for s in row['skill_list'].split(',')]
            for skill in skills:
                if skill in skill_set and skill != target_skill.lower():
                    skill_counter[skill] += 1
                    
    # 3. 返回前5个最高频技能
    return dict(sorted(skill_counter.items(), key=lambda x: x[1], reverse=True)[:5])

def compare_str(str1, key):
    """模糊匹配字符串"""
    return key.lower() in str1.lower()

# 3. 大模型交互工具
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_skill_recommendation",
            "description": "根据用户技能推荐相关技术和学习方向",
            "parameters": {
                "type": "object",
                "properties": {
                    "skill": {"type": "string", "description": "技能名称，如java、python、c++"}
                },
                "required": ["skill"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "find_related_positions",
            "description": "根据技能查找最相关的5个高频岗位",
            "parameters": {
                "type": "object",
                "properties": {
                    "skill": {"type": "string", "description": "技能名称，如java、linux"}
                },
                "required": ["skill"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_position_requirements",
            "description": "根据岗位名称查找最需要的5个核心技能",
            "parameters": {
                "type": "object",
                "properties": {
                    "position_name": {"type": "string", "description": "岗位名称或关键词，如嵌入式、Java工程师"}
                },
                "required": ["position_name"]
            }
        }
    }
]

# 4. 执行函数
def execute_function(func_name, **kwargs):
    if func_name == "get_skill_recommendation":
        result = get_associated_skills(kwargs['skill'])
        prompt = f"请根据以下技能关联数据给出学习建议，不要编造信息：{result}"
    elif func_name == "find_related_positions":
        result = cacu_skill_position_wordcount(dataset, kwargs['skill'])
        prompt = f"请根据以下岗位分布数据给出职业发展建议：{result}"
    elif func_name == "get_position_requirements":
        result = cacu_postion_skill_wordcount(dataset, kwargs['position_name'])
        prompt = f"请根据以下技能要求数据给出学习路径建议：{result}"
    else:
        raise ValueError(f"未知函数: {func_name}")
    
    return {"result": result, "prompt": prompt}

# 5. 界面设计
st.title("🔍 技能-岗位精准推荐系统")
st.markdown("**精准推荐前5个最相关结果**")
st.markdown("""
### 支持三类核心问题：
1. **技能→岗位**：我已经掌握了Java，适合哪些岗位？
2. **技能→技能**：我C++不错，还应该学什么？
3. **岗位→技能**：嵌入式岗位需要什么技能？
""")

# 主界面
query_type = st.radio(
    "请选择查询类型:", 
    ["技能→岗位", "技能→技能", "岗位→技能"],
    horizontal=True
)

user_input = st.text_input("请输入查询内容:")

if st.button("获取推荐"):
    with st.spinner("正在分析..."):
        try:
            # 显示函数调用信息
            st.subheader("🔧 函数调用详情")
            
            # 构造大模型请求
            if query_type == "技能→岗位":
                st.code(f"调用函数：find_related_positions(skill='{user_input}')")
                response = client.chat.completions.create(
                    model="glm-4",
                    messages=[{"role": "user", "content": f"掌握{user_input}可以从事什么岗位？"}],
                    tools=[tools[1]],
                    tool_choice={"type": "function", "function": {"name": "find_related_positions"}}
                )
            elif query_type == "技能→技能":
                st.code(f"调用函数：get_skill_recommendation(skill='{user_input}')")
                response = client.chat.completions.create(
                    model="glm-4",
                    messages=[{"role": "user", "content": f"我{user_input}学得不错，请推荐相关技术"}],
                    tools=[tools[0]],
                    tool_choice={"type": "function", "function": {"name": "get_skill_recommendation"}}
                )
            else:
                st.code(f"调用函数：get_position_requirements(position_name='{user_input}')")
                response = client.chat.completions.create(
                    model="glm-4",
                    messages=[{"role": "user", "content": f"{user_input}岗位需要什么技能？"}],
                    tools=[tools[2]],
                    tool_choice={"type": "function", "function": {"name": "get_position_requirements"}}
                )

            # 解析并执行函数
            if response.choices[0].message.tool_calls:
                tool_call = response.choices[0].message.tool_calls[0]
                func_name = tool_call.function.name
                kwargs = json.loads(tool_call.function.arguments)
                
                st.code(f"参数详情：{kwargs}")
                result = execute_function(func_name, **kwargs)
                
                # 显示原始数据
                st.subheader("📊 分析结果（前5名）")
                if isinstance(result["result"], dict):
                    df = pd.DataFrame(result["result"].items(), columns=['名称', '出现频次'])
                else:
                    df = pd.DataFrame({"技能": list(result["result"])})
                
                st.dataframe(df.sort_values('出现频次' if '出现频次' in df.columns else '技能', 
                                          ascending=False))
                
                # 生成自然语言回复
                st.subheader("💡 专业建议（基于数据分析）")
                llm_response = client.chat.completions.create(
                    model="glm-4",
                    messages=[{
                        "role": "user", 
                        "content": result["prompt"] + "\n\n请用简洁专业的语言给出建议，不要编造数据"
                    }],
                    temperature=0.7
                )
                
                st.success(llm_response.choices[0].message.content)
            else:
                st.warning("未识别到有效的函数调用")
        except Exception as e:
            st.error(f"处理出错: {str(e)}")

# 数据样本展示
if st.sidebar.checkbox("显示数据样本"):
    st.subheader("招聘数据样本")
    st.dataframe(dataset[['positionName', 'skill_list']].head(5))